﻿using ClosedXML.Excel;
using Microsoft.Extensions.Configuration;
using Spectre.Console;
using System.ComponentModel;
using System.Diagnostics;
using System.Xml.Linq;
using WorkTool.Helpers;

namespace WorkTool
{
    public class HolidayStatistics : ITools
    {
        private static HCMInfo? _hcmInfo = null;

        public void ToolsMethod(IConfigurationRoot config)
        {
            var options = new List<(int Index, string Description)>{
                new (1, "本月"),
                new (2, "上月"),
                new (3, "全部"),
                new (4, "自定义"),
                new (0, "返回上一级")
            };
            var ynOptions = new List<(int Index, string Description)>{
                new (1, "是"),
                new (0, "否")
            };
            DateTime? date = null;
            while (true)
            {
                ToolHelper.ConsoleClear();
                var selection = AnsiConsole.Prompt(
                    new SelectionPrompt<(int Index, string Description)>()
                        .Title("[green1]请选择：[/]")
                        .PageSize(10)
                        .UseConverter(option => $"[yellow]【{option.Description}】[/]")
                        .AddChoices(options));
                switch (selection.Index)
                {
                    case 1:
                        date = DateTime.Now;
                        break;

                    case 2:
                        date = DateTime.Now.Date.AddMonths(-1);
                        break;

                    case 3:
                        date = null;
                        break;

                    case 4:
                        while (true)
                        {
                            var dateReadLine = AnsiConsole.Ask<string>("[bold][green1]请输入要查询的月份（格式：yyyy-MM）：[/] [/]");
                            if (DateTime.TryParse(dateReadLine, out var dt))
                            {
                                date = dt;
                                break;
                            }
                            else
                            {
                                AnsiConsole.MarkupLine("[yellow]格式错误，请重新输入！[/]");
                            }
                        }
                        break;

                    case 0:
                        AnsiConsole.MarkupLine("[green]正在返回上一级...[/]");
                        return;

                    default:
                        break;
                }
                ToolHelper.ConsoleClear();
                AnsiConsole.Markup($"[bold][aqua]当前选择：【{(date.HasValue ? "查询月份：" + date.Value.ToString("yyyy-MM") : "查询全部数据")}】[/][/] ");
                Console.SetCursorPosition(0, 2);
                AnsiConsole.Status().Start("数据加载中...", ctx =>
                {
                    ctx.Spinner(Spinner.Known.Star);
                    ctx.SpinnerStyle(Style.Parse("green"));
                    Task.Run(async () =>
                    {
                        ctx.Status("正在获取用户信息...");
                        ctx.Spinner(Spinner.Known.Star);
                        ctx.SpinnerStyle(Style.Parse("green"));
                        if (_hcmInfo == null)
                            await SetHCMInfo(SettingsHelper._holidayStatisticsSettings);
                        ctx.Status("正在获取假期结余...");
                        ctx.Spinner(Spinner.Known.Star);
                        ctx.SpinnerStyle(Style.Parse("green"));
                        if (!await GetHolidayBalance())
                        {
                            await SetHCMInfo(SettingsHelper._holidayStatisticsSettings);
                            await GetHolidayBalance();
                        }
                        ctx.Status("正在获取请假记录...");
                        ctx.Spinner(Spinner.Known.Star);
                        ctx.SpinnerStyle(Style.Parse("green"));
                        var myHolidayStatisticsList = await GetHolidayStatistics(date);
                        ConsoleTablePrinter.PrintEnhancedTable(myHolidayStatisticsList);
                        ctx.Status("正在生成日历中...");
                        ctx.Spinner(Spinner.Known.Star);
                        ctx.SpinnerStyle(Spectre.Console.Style.Parse("green"));
                        var lunchAllowanceStatisticsList = new List<LunchAllowanceStatistics>();
                        var calendarDate = new List<CalendarData>();
                        var calendarYear = new List<DateTime>();
                        if (date.HasValue)
                            calendarYear.Add(date.Value);
                        calendarYear.AddRange(myHolidayStatisticsList.Select(x => x.StartTime.Date));
                        calendarYear.AddRange(myHolidayStatisticsList.Select(x => x.EndTime.Date));
                        foreach (var year in calendarYear.Select(x => x.Year).Distinct())
                        {
                            var temp = CalendarHelper.GetCalendarSettings(config, year);
                            if (temp.Count == 0)
                                temp = await GetHcmCalendarData(year);
                            calendarDate.AddRange(temp);
                        }
                        foreach (var myHolidayStatistics in myHolidayStatisticsList)
                        {
                            for (var day = myHolidayStatistics.StartTime.Date; day <= myHolidayStatistics.EndTime.Date; day = day.AddDays(1))
                            {
                                var calendarDay = calendarDate.Where(x => x.Date.Equals(day)).ToList();
                                if (calendarDay.Count > 0)
                                {
                                    if (calendarDay.Any(x => x.CalendarDateStatus.Equals(CalendarDateStatus.DayOff)))
                                        continue;
                                }
                                else
                                {
                                    if ((int)day.DayOfWeek == 0 || (int)day.DayOfWeek == 6)
                                        continue;
                                }
                                var tempStart = day > myHolidayStatistics.StartTime ? day.AddHours(9) : myHolidayStatistics.StartTime;
                                var tempEnd = day.Date < myHolidayStatistics.EndTime.Date ? day.AddHours(18) : myHolidayStatistics.EndTime;
                                var myCalendarData = new CalendarData
                                {
                                    Date = day,
                                    CalendarDateStatus = CalendarDateStatus.Leave,
                                    CalendarLeaveData = new CalendarLeaveData { LeaveName = myHolidayStatistics.LeaveName }
                                };
                                if (tempStart.Hour <= 9 && tempEnd.Hour >= 17)
                                    myCalendarData.CalendarLeaveData.LeaveTimeType = LeaveTimeType.All;
                                else
                                if (tempStart.Hour <= 9 && tempEnd.Hour < 17)
                                    myCalendarData.CalendarLeaveData.LeaveTimeType = LeaveTimeType.AM;
                                else
                                if (tempStart.Hour > 9)
                                    myCalendarData.CalendarLeaveData.LeaveTimeType = LeaveTimeType.PM;
                                calendarDate.Add(myCalendarData);
                                lunchAllowanceStatisticsList.Add(new LunchAllowanceStatistics
                                {
                                    Day = day.Day,
                                    CalendarDateStatus = CalendarDateStatus.Leave,
                                    LeaveName = myHolidayStatistics.LeaveName == "年假" ? "年休假" : myHolidayStatistics.LeaveName,
                                    LeaveTime = myCalendarData.CalendarLeaveData.LeaveTimeType
                                });
                            }
                        }
                        foreach (var date in calendarYear.OrderBy(x => x).Select(x => new
                        {
                            x.Year,
                            x.Month
                        }).Distinct())
                        {
                            CalendarHelper.CreateCalendar(date.Year, date.Month, calendarDate.Where(x => x.Date.Year.Equals(date.Year) && x.Date.Month.Equals(date.Month)).ToList());
                        }
                        if (date.HasValue)
                        {
                            ctx.Status("等待中...");
                            ctx.Spinner(Spinner.Known.Star);
                            ctx.SpinnerStyle(Spectre.Console.Style.Parse("green"));
                            var selection = AnsiConsole.Prompt(new SelectionPrompt<(int Index, string Description)>()
                                .Title("[green1]是否生成午餐津贴统计表？[/]")
                                .PageSize(10)
                                .UseConverter(option => $"[yellow]【{option.Description}】[/]")
                                .AddChoices(ynOptions));
                            switch (selection.Index)
                            {
                                case 0:
                                    break;

                                case 1:
                                    ctx.Status("生成Excel文件中...");
                                    ctx.Spinner(Spinner.Known.Star);
                                    ctx.SpinnerStyle(Spectre.Console.Style.Parse("green"));
                                    Thread.Sleep(1000);
                                    ExportReport(config, date.Value, calendarDate, lunchAllowanceStatisticsList, _hcmInfo.UserCode);
                                    break;

                                default:
                                    break;
                            }
                        }
                    }).Wait();
                });
                AnsiConsole.MarkupLine("[grey]按任意键继续...[/]");
                Console.ReadKey();
            }
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="holidayStatisticsSettings"></param>
        /// <returns></returns>
        private async Task SetHCMInfo(HolidayStatisticsSettings holidayStatisticsSettings)
        {
            var result = new HCMInfo();
            using var client = new HttpClient();
            var tokenRequest = new HttpRequestMessage(HttpMethod.Get, "https://wfm.platinumchina.com/workforce/Handlers/MobileHandler.ashx")
            {
                Content = new StringContent($"<Message ID=\"msg1\" MessageType=\"InvokeServiceMessage\" Service=\"Login\" Method=\"LoginByUserCodePwd\" Language=\"Chinese\" UserCode=\"{holidayStatisticsSettings.Username}\" LoginUserCode=\"\" TokenID=\"\" ClientType=\"Web\" ShellPlatform=\"Browser\" URL=\"/\" StartHandlerIndex=\"0\"><Parameters><String>{holidayStatisticsSettings.Username}</String><String>{holidayStatisticsSettings.Password.CalculateMD5().CalculateMD5()}</String><String/><String/><null/><String/></Parameters></Message>", null, "application/xml")
            };
            var tokenResponse = await client.SendAsync(tokenRequest);
            tokenResponse.EnsureSuccessStatusCode();
            var tokenString = await tokenResponse.Content.ReadAsStringAsync();
            var tokenXml = XDocument.Parse(tokenString);
            result.TokenId = tokenXml.Descendants("String").FirstOrDefault(e => (string)e.Attribute("Name") == "tokenId")?.Value;
            result.UserId = tokenXml.Descendants("String").FirstOrDefault(e => (string)e.Attribute("Name") == "userId")?.Value;
            result.UserCode = tokenXml.Descendants("String").FirstOrDefault(e => (string)e.Attribute("Name") == "userCode")?.Value;
            _hcmInfo = result;
        }

        /// <summary>
        /// 查询假期结余
        /// </summary>
        /// <returns></returns>
        private async Task<bool> GetHolidayBalance()
        {
            using var client = new HttpClient();
            var holidayBalanceMessage = $"<Message ID=\"msg1\" MessageType=\"InvokeServiceMessage\" Service=\"AnnualLeave\" Method=\"GetPersonalLeaveInfo\" Language=\"Chinese\" UserCode=\"{_hcmInfo.UserCode}\" LoginUserCode=\"{_hcmInfo.UserCode}\" TokenID=\"\" ClientType=\"Web\" ShellPlatform=\"Browser\" URL=\"/Home/MyPaidLeaveInfo\" StartHandlerIndex=\"0\"><Parameters><String>{_hcmInfo.UserId}</String></Parameters></Message>";
            var holidayBalanceRequestHash = (holidayBalanceMessage.EscapeDataString() + _hcmInfo.TokenId).CalculateMD5();
            var holidayBalanceRequest = new HttpRequestMessage(HttpMethod.Get, "https://wfm.platinumchina.com/workforce/Handlers/MobileHandler.ashx?MessageHash=" + holidayBalanceRequestHash)
            {
                Content = new StringContent(holidayBalanceMessage)
            };
            var holidayBalanceResponse = await client.SendAsync(holidayBalanceRequest);
            holidayBalanceResponse.EnsureSuccessStatusCode();
            var holidayBalanceString = await holidayBalanceResponse.Content.ReadAsStringAsync();
            var holidayBalanceXml = XDocument.Parse(holidayBalanceString);
            var anlvInfo = holidayBalanceXml.Descendants("DataTable").FirstOrDefault(dt => dt.Attribute("Name")?.Value == "anlvInfo");
            var holidayBalanceDic = new Dictionary<string, string>
                        {
                            { "假期名称", "结余" }
                        };
            if (anlvInfo != null)
            {
                var columns = anlvInfo.Element("Columns")?.Elements("Column").Select(col => col.Attribute("Name")?.Value ?? "UnnamedColumn").ToList();
                holidayBalanceDic.Add("年假", anlvInfo.Element("Rows")?.Elements("Row").Elements().ToList()[columns.IndexOf("restCurYear")].Value.ToString());
            }
            var otherInfo = holidayBalanceXml.Descendants("DataTable").FirstOrDefault(dt => dt.Attribute("Name")?.Value == "otherInfo");
            if (otherInfo != null)
            {
                var columns = otherInfo.Element("Columns")?.Elements("Column").Select(col => col.Attribute("Name")?.Value ?? "UnnamedColumn").ToList();
                var holidayName = columns.IndexOf("c_name");
                var holiday = columns.IndexOf("restBalance");
                foreach (var row in otherInfo.Element("Rows")?.Elements("Row").ToList())
                {
                    var values = row.Elements().ToList();
                    holidayBalanceDic.Add(values[holidayName].Value.ToString(), values[holiday].Value.ToString());
                }
            }
            if (holidayBalanceDic.Count > 1)
            {
                var table = new Table
                {
                    Border = TableBorder.Rounded,
                    BorderStyle = new Style(Color.DarkCyan),
                };
                table.AddColumns(holidayBalanceDic.Keys.ToArray());
                table.AddRow(holidayBalanceDic.Values.ToArray());
                AnsiConsole.Write(table);
                return true;
            }
            return false;
        }

        /// <summary>
        /// 查询请假记录
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        private async Task<List<CalendarData>> GetHcmCalendarData(int year)
        {
            using var client = new HttpClient();
            var calendarDataList = new List<CalendarData>();
            var holidayCalendarMessage = $"<Message ID=\"msg1\" MessageType=\"InvokeServiceMessage\" Service=\"YearAtt\" Method=\"GetHughClassListByUseridAndDate\" Language=\"Chinese\" UserCode=\"{_hcmInfo.UserCode}\" LoginUserCode=\"{_hcmInfo.UserCode}\" TokenID=\"\" ClientType=\"Web\" ShellPlatform=\"Browser\" URL=\"/Home/MyCalendar\" StartHandlerIndex=\"0\"><Parameters><String>{_hcmInfo.UserId}</String><DateTime>{year}-01-01 00:00:00</DateTime><DateTime>{year}-12-31 23:59:59</DateTime></Parameters></Message>";
            var holidayCalendarRequestHash = (holidayCalendarMessage.EscapeDataString() + _hcmInfo.TokenId).CalculateMD5();
            var holidayCalendarRequest = new HttpRequestMessage(HttpMethod.Get, "https://wfm.platinumchina.com/workforce/Handlers/MobileHandler.ashx?MessageHash=" + holidayCalendarRequestHash)
            {
                Content = new StringContent(holidayCalendarMessage)
            };
            var holidayCalendarResponse = await client.SendAsync(holidayCalendarRequest);
            holidayCalendarResponse.EnsureSuccessStatusCode();
            var holidayCalendarString = await holidayCalendarResponse.Content.ReadAsStringAsync();
            var holidayCalendarXml = XDocument.Parse(holidayCalendarString);
            var holidayCalendar = holidayCalendarXml.Descendants("DataTable").FirstOrDefault(dt => dt.Attribute("Name")?.Value == "ReturnData");
            if (holidayCalendar != null)
            {
                foreach (var row in holidayCalendar.Element("Rows")?.Elements("Row").ToList())
                {
                    var values = row.Elements().ToList();
                    var type = int.Parse(values[1].Value);
                    var day = DateTime.Parse(values[0].Value).Date;
                    var calendarData = new CalendarData
                    {
                        Date = day
                    };
                    switch (type)
                    {
                        case 0:
                        case 1:
                            calendarData.CalendarDateStatus = CalendarDateStatus.DayOff;
                            break;

                        case 2:
                            calendarData.CalendarDateStatus = CalendarDateStatus.WorkingDays1;
                            break;

                        default:
                            break;
                    }
                    calendarDataList.Add(calendarData);
                }
            }
            return calendarDataList;
        }

        /// <summary>
        /// 查询请假记录
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        private async Task<List<HolidayStatisticsData>> GetHolidayStatistics(DateTime? date)
        {
            var leaveResultList = new List<HolidayStatisticsData>();
            using var client = new HttpClient();
            var leaveMessage = "<Message ID=\"msg1\" MessageType=\"InvokeServiceMessage\" Service=\"Workflow\" Method=\"{0}\" Language=\"Chinese\" UserCode=\"{1}\" LoginUserCode=\"{1}\" TokenID=\"\" ClientType=\"Web\" ShellPlatform=\"Browser\" URL=\"/Home/myApplicationList\" StartHandlerIndex=\"0\"><Parameters><Dictionary><Int Name=\"start\">0</Int><Int Name=\"limit\">99999</Int><String Name=\"sort\">createtime desc</String><String Name=\"filter\"/><String Name=\"currentUserId\">{2}</String><Int Name=\"page\">1</Int><String Name=\"searchemp\"/><String Name=\"searchkeyword\"/><null Name=\"createtimefrom\"/><null Name=\"createtimeto\"/>";
            if (date.HasValue)
            {
                var firstDayOfMonth = new DateTime(date.Value.Year, date.Value.Month, 1);
                var lastDayOfMonth = firstDayOfMonth.AddMonths(1).AddDays(-1);
                leaveMessage += $"<DateTime Name=\"starttimefrom\">{firstDayOfMonth:yyyy-MM-dd} 00:00:00</DateTime><DateTime Name=\"starttimeto\">{lastDayOfMonth:yyyy-MM-dd} 23:59:59</DateTime>";
            }
            else
            {
                leaveMessage += "<null Name=\"starttimefrom\"/><null Name=\"starttimeto\"/>";
            }
            leaveMessage += "<String Name=\"processtype\">wfmleave</String><Bool Name=\"queryhistory\">false</Bool></Dictionary></Parameters></Message>";
            var waitingRequest = string.Format(leaveMessage, "GetMyWaitingProcessWithBizData", _hcmInfo.UserCode, _hcmInfo.UserId);
            var waitingRequestHash = (waitingRequest.EscapeDataString() + _hcmInfo.TokenId).CalculateMD5();
            var completedRequest = string.Format(leaveMessage, "GetMyCompletedProcessWithBizData", _hcmInfo.UserCode, _hcmInfo.UserId);
            var completedRequestHash = (completedRequest.EscapeDataString() + _hcmInfo.TokenId).CalculateMD5();
            var leaveRequestDic = new Dictionary<string, string> {
                            { waitingRequestHash, waitingRequest },
                            { completedRequestHash, completedRequest },
                        };
            foreach (var item in leaveRequestDic)
            {
                var leaveRequest = new HttpRequestMessage(HttpMethod.Get, "https://wfm.platinumchina.com/workforce/Handlers/MobileHandler.ashx?MessageHash=" + item.Key)
                {
                    Content = new StringContent(item.Value)
                };
                var leaveResponse = await client.SendAsync(leaveRequest);
                leaveResponse.EnsureSuccessStatusCode();
                var leaveString = await leaveResponse.Content.ReadAsStringAsync();
                var leaveXml = XDocument.Parse(leaveString);
                var mainDataTable = leaveXml.Descendants("DataTable").FirstOrDefault(dt => dt.Attribute("Name")?.Value == "$");
                if (mainDataTable != null)
                {
                    var columns = mainDataTable.Element("Columns")?.Elements("Column")
                                             .Select((col, index) => new
                                             {
                                                 Name = col.Attribute("Name")?.Value,
                                                 DataType = col.Attribute("DataType")?.Value,
                                                 Index = index
                                             })
                                             .ToList();
                    var rows = mainDataTable.Element("Rows")?.Elements("Row");
                    if (columns != null && rows != null)
                    {
                        foreach (var row in rows)
                        {
                            var rowDict = new Dictionary<string, string>();
                            foreach (var column in columns)
                            {
                                if (string.IsNullOrEmpty(column.Name)) continue;
                                var element = row.Elements().ElementAt(column.Index);
                                rowDict[column.Name] = element.Value;
                            }
                            if (rowDict["processresult"] != "Rejected")
                            {
                                leaveResultList.Add(new HolidayStatisticsData
                                {
                                    LeaveName = rowDict["biz_leavename_c"],
                                    ApplyNums = rowDict["biz_applynums"],
                                    UnitName = rowDict["biz_unitcnname"],
                                    StartTime = DateTime.Parse(rowDict["starttime"]),
                                    EndTime = DateTime.Parse(rowDict["biz_enddate"]),
                                    Status = rowDict["status"] == "Started" ? "审批中" : "已完成"
                                });
                            }
                        }
                    }
                }
            }
            return leaveResultList;
        }

        /// <summary>
        /// 导出午餐津贴统计表
        /// </summary>
        /// <param name="config"></param>
        /// <param name="date"></param>
        /// <param name="calendarDate"></param>
        /// <param name="lunchAllowanceStatisticsList"></param>
        private void ExportReport(IConfigurationRoot config, DateTime date, List<CalendarData> calendarDate, List<LunchAllowanceStatistics> lunchAllowanceStatisticsList, string signature)
        {
            var firstDayOfMonth = date.AddDays(1 - date.Day);
            var daysInMonth = DateTime.DaysInMonth(date.Year, date.Month);
            var currentDay = 1;
            while (currentDay <= daysInMonth)
            {
                if (!lunchAllowanceStatisticsList.Any(x => x.Day.Equals(currentDay)))
                {
                    var day = new DateTime(date.Year, date.Month, currentDay);
                    var lunchAllowanceStatistics = new LunchAllowanceStatistics
                    {
                        Day = currentDay,
                        CalendarDateStatus = ((int)day.DayOfWeek == 0 || (int)day.DayOfWeek == 6) ? CalendarDateStatus.DayOff : CalendarDateStatus.WorkingDays,
                    };
                    var temp = calendarDate.FirstOrDefault(x => x.Date.Equals(day));
                    if (temp != null)
                    {
                        lunchAllowanceStatistics.CalendarDateStatus = temp.CalendarDateStatus;
                    }
                    lunchAllowanceStatisticsList.Add(lunchAllowanceStatistics);
                }
                currentDay++;
            }
            using var workbook = new XLWorkbook(Path.Combine(Directory.GetCurrentDirectory(), "LunchAllowanceStatisticsTemplate.xlsx"));
            var codesheet = workbook.Worksheet(2);
            var leaveCodeList = new List<LeaveTypeCode>();
            foreach (var row in codesheet.RowsUsed().Skip(1))
            {
                leaveCodeList.Add(new LeaveTypeCode()
                {
                    Code = row.Cell(1).Value.ToString(),
                    Description = row.Cell(2).Value.ToString()
                });
            }
            var worksheet = workbook.Worksheet(1);
            worksheet.Cell(11, 2).SetValue($"{ToolHelper._month[date.ToString("MM")]} 1-{ToolHelper._month[date.ToString("MM")]} {lunchAllowanceStatisticsList.Count},{date:yyyy}");
            var rowIndex = 16;
            foreach (var item in lunchAllowanceStatisticsList.OrderBy(x => x.Day).GroupBy(x => x.Day))
            {
                worksheet.Cell(rowIndex, 1).SetValue(item.Key);
                var remarks = new List<string>();
                var allowance = "Y";
                foreach (var l in item)
                {
                    if (l.Allowance.Equals("N"))
                        allowance = l.Allowance;
                    if (l.LeaveTime.HasValue)
                    {
                        var remark = string.Empty;
                        switch (l.LeaveTime.Value)
                        {
                            case LeaveTimeType.All:
                                remark = l.LeaveName + "（全天）";
                                break;

                            case LeaveTimeType.AM:
                                remark = "上午" + l.LeaveName;
                                break;

                            case LeaveTimeType.PM:
                                remark = "下午" + l.LeaveName;
                                break;

                            default:
                                break;
                        }
                        remarks.Add(remark);
                    }
                }
                worksheet.Cell(rowIndex, 2).SetValue(item.Any(x => x.Allowance.Equals("N")) ? "N" : "Y");
                switch (SettingsHelper._holidayStatisticsSettings.AllowanceRemarks)
                {
                    case 1:
                        if (allowance.Equals("Y") && remarks.Count == 0)
                            remarks.Add("出勤");
                        break;

                    case 2:
                        break;

                    case 3:
                        if (remarks.Count == 1 && remarks.Any(x => x.Contains("下午")))
                            remarks = [];
                        break;

                    default:
                        break;
                }
                if (remarks.Count > 0)
                {
                    var remark = string.Join("/", remarks.Distinct());

                    if (!string.IsNullOrEmpty(remark))
                        worksheet.Cell(rowIndex, 3).SetValue(leaveCodeList.FirstOrDefault(x => x.Description.Equals(remark))?.Code);
                }
                if (item.First().CalendarDateStatus.Equals(CalendarDateStatus.DayOff))
                    worksheet.Row(rowIndex).Cells(1, 3).Style.Fill.SetBackgroundColor(XLColor.FromArgb(250, 191, 143));
                rowIndex++;
            }
            worksheet.Cell(47, 2).FormulaA1 = $"=COUNTIF(B16:B{rowIndex - 1},\"Y\")";
            worksheet.Cell(48, 2).SetValue(signature);
            if (rowIndex <= 46)
                worksheet.Rows(rowIndex, 46).Delete();
            workbook.RecalculateAllFormulas();
            var excelPath = Path.Combine(SettingsHelper._fileSettings.SaveFolder, $"午餐津贴统计表 {ToolHelper._month[date.ToString("MM")]}.,{date:yyyy}_{signature}{(SettingsHelper._fileSettings.SaveFileNameRandom ? $"_{new Random().Next(10000, 99999)}" : "")}.xlsx");
            workbook.SaveAs(excelPath);
            AnsiConsole.MarkupLine($"[green1]文件已保存至\n[/] [bold][aqua]{excelPath}[/][/]");
            Process.Start(new ProcessStartInfo
            {
                FileName = excelPath,
                UseShellExecute = true
            });
        }
    }

    public class LeaveTypeCode
    {
        public string Code { get; set; }

        public string Description { get; set; }
    }

    public class HolidayStatisticsData
    {
        /// <summary>
        /// 休假类型
        /// </summary>
        [Description("休假类型")]
        public string LeaveName { get; set; }

        /// <summary>
        /// 休假时长
        /// </summary>
        [Description("休假时长")]
        public string ApplyNums { get; set; }

        /// <summary>
        /// 休假单位
        /// </summary>
        [Description("休假单位")]
        public string UnitName { get; set; }

        /// <summary>
        /// 开始时间
        /// </summary>
        [Description("开始时间")]
        public DateTime StartTime { get; set; }

        /// <summary>
        /// 结束时间
        /// </summary>
        [Description("结束时间")]
        public DateTime EndTime { get; set; }

        /// <summary>
        /// 审批状态
        /// </summary>
        [Description("审批状态")]
        public string Status { get; set; }
    }

    public class LunchAllowanceStatistics
    {
        /// <summary>
        /// 日期
        /// </summary>
        public int Day { get; set; }

        /// <summary>
        /// 日期状态
        /// </summary>
        public CalendarDateStatus CalendarDateStatus { get; set; }

        /// <summary>
        /// 休假名称
        /// </summary>
        public string LeaveName { get; set; }

        /// <summary>
        /// 请假时间
        /// </summary>
        public LeaveTimeType? LeaveTime { get; set; }

        /// <summary>
        /// 津贴
        /// </summary>
        public string Allowance
        {
            get
            {
                if (CalendarDateStatus.Equals(CalendarDateStatus.DayOff))
                    return "N";
                if (LeaveTime.HasValue)
                {
                    if (LeaveTime.Value.Equals(LeaveTimeType.PM))
                    {
                        return "Y";
                    }
                    return "N";
                }
                else
                {
                    return "Y";
                }
            }
        }
    }

    public class HCMInfo
    {
        /// <summary>
        /// token id
        /// </summary>
        public string TokenId { get; set; }

        /// <summary>
        /// user id
        /// </summary>
        public string UserId { get; set; }

        /// <summary>
        /// user code
        /// </summary>
        public string UserCode { get; set; }
    }
}